<?php

namespace app\controllers\h5;

use app\commission\Commission;
use app\commission\PaidFinish;
use app\controllers\h5\base\H5Controller;
use app\models\merchant\Merchant;
use app\models\merchant\Merchant as Model;
use app\models\merchant\MerchantImage;
use app\models\merchant\MerchantOrder;
use app\models\merchant\MerchantPayFor;
use app\models\merchant\MerchantType;
use app\models\system\SetApp;
use app\models\system\SetBasic;
use app\models\system\SetMerchant;
use app\models\user\UserAccount;
use app\redis\Cache;
use app\services\Upload;
use app\util\Qrcode;

/**
 * Class MerchantController
 * @package app\controllers\h5
 */
class MerchantController extends H5Controller
{
    /**
     * merchant list
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionList()
    {
        $type = $this->post('type');

        $page = intval($this->post('page', $this->page));
        $pageSize = intval($this->post('pageSize', $this->pageSize));

        $key = Cache::$MERCHANT . $type . '-' . $page;
        $cache = Cache::get($key);
        if (!$cache) {
            $query = Model::find()
                ->where(['status' => Model::$statusMapping['OK']])
                ->andWhere(['type' => $type]);

            $totalCount = $query->count();
            $totalPage = ceil($totalCount / $pageSize);

            $list = $query->orderBy(['sort' => SORT_ASC, 'id' => SORT_DESC])
                ->offset(($page - 1) * $pageSize)
                ->limit($pageSize)
                ->with(['image'])
                ->asArray()
                ->all();

            Cache::set($key, json_encode([
                'list' => $list,
                'totalCount' => $totalCount,
                'totalPage' => $totalPage
            ]));
        } else {
            $data = json_decode($cache, true);
            $list = $data['list'];
            $totalCount = $data['totalCount'];
            $totalPage = $data['totalPage'];
        }

        return $this->successEncode([
            $this->list => $list,
            $this->totalCount => (int)$totalCount,
            $this->totalPage => $totalPage,
            $this->currentPage => $page
        ]);
    }

    /**
     * check merchant
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionCheckMerchant()
    {
        $id = $this->user->id;

        $model = Model::find()
            ->where(['user_id' => $id])
            ->select(['status', 'user_id', 'reject'])
            ->one();

        if (!$model) {
            // no register
            return $this->successEncode([
                'is_exist' => false,
                'status' => -100,
                'reject' => ''
            ]);
        }

        // is exist
        return $this->successEncode([
            'is_exist' => true,
            'status' => intval($model->status),
            'reject' => $model->reject
        ]);
    }

    /**
     * merchant type list (differ uni type)
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionTypeList()
    {
        $key = Cache::$MERCHANT_TYPE;
        $cache = Cache::get($key);
        if (!$cache) {
            $list = MerchantType::find()
                ->where(['status' => MerchantType::$statusMapping['OK']])
                ->select(['id', 'name'])
                ->orderBy(['sort' => SORT_ASC, 'id' => SORT_ASC])
                ->asArray()
                ->all();
            Cache::set($key, json_encode($list));
        } else {
            $list = json_decode($cache, true);
        }

        return $this->successEncode($list);
    }

    /**
     * Register image upload
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionUpload()
    {
        $bucket = $this->get('bucket');
        $result = Upload::uploadImage($bucket);

        if ($result) {
            return $this->successEncode($result['id'], '上传成功');
        }

        return $this->fail('上传失败');
    }

    /**
     * merchant edit
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionEdit()
    {
        $model = Model::find()
            ->where(['user_id' => $this->user->id])
            ->with(['images', 'images.image'])
            ->asArray()
            ->one();

        if ($model) {
            return $this->successEncode($model);
        }

        return $this->fail();
    }

    /**
     * register submit
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionSubmit()
    {
        $data = $this->post();

        $transaction = \Yii::$app->db->beginTransaction();

        try {
            $model = Model::findOne(['user_id' => $this->user->id]);
            if (!$model) {
                $model = new Model();
                $model->user_id = $this->user->id;
            } else {
                // edit => delete image
                MerchantImage::deleteAll(['merchant_id' => $model->id]);

                // status
                $model->status = 0;
                $model->save();
            }

            $data = ['Merchant' => $data];
            if ($model->load($data) && $model->save()) {

                // insert image list
                $licenses = $this->post('license_list');
                $ids = $this->post('id_list');
                $shops = $this->post('shop_list');

                $this->updateImage($model, $licenses, 1);
                $this->updateImage($model, $ids, 2);
                $this->updateImage($model, $shops, 3);

                // main image
                if ($shops) {
                    $model->image_id = $shops[0];
                    $model->save();
                }
            }

            $transaction->commit();

            return $this->success([], '提交成功,请耐心等待审核...');

        } catch (\Exception $e) {
            $transaction->rollBack();

            // return $this->fail($e->getMessage());
            return $this->fail();
        }
    }

    // edit image upload
    private function updateImage(Merchant $merchant, $list, $type)
    {
        if ($list) {
            foreach ($list as $item) {
                $m = new MerchantImage();
                $m->merchant_id = $merchant->id;
                $m->image_id = $item;
                $m->type = $type;
                $m->save();
            }
        }
    }

    /**
     * merchant view (profile)
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionView()
    {
        $id = intval($this->post('id'));
        $user_id = intval($this->post('user_id'));

        $key = Cache::$MERCHANT_VIEW . $id;
        $cache = Cache::get($key);

        if ($cache) {
            $data = json_decode($cache, true);

            return $this->successEncode([
                'data' => $data['data'],
                'qrcode' => $data['qrcode'],
                'qrcode_real' => $data['qrcode_real'],
                'text' => $data['debug_text'],
                'cache' => true,
            ]);
        }

        $query = Model::find();

        // view or myself
        if ($id) {
            $query->where(['id' => $id]);
        } else if ($user_id) {
            $query->where(['user_id' => $user_id]);
        } else {
            return $this->fail();
        }

        $model = $query->with(['images', 'images.image'])
            ->asArray()
            ->one();

        // only show shop image list
        $shopList = [];
        if ($model['images']) {
            foreach ($model['images'] as $item) {
                if ($item['type'] == 3) {
                    array_push($shopList, $item);
                }
            }
        }
        $model['images'] = $shopList;

        if ($model) {
            // clear
            unset($model['bank_name'], $model['bank_number'], $model['difference']);

            // image id
            $image_id = SetMerchant::getLastOne();
            $image_id = $image_id->qrcode_background;

            $set = SetApp::getLastOne();
            $name = '/qrcode/merchant-pay/' . $model['id'] . '.png';
            $real = '/qrcode/merchant-pay/' . $model['id'] . '-' . $image_id . '-real.png';
            $string = $set->domain . $set->merchant . '/' . $model['id'];

            if (!Qrcode::isExist($name) || !Qrcode::isExist($real)) {
                Qrcode::generate($string, $name, 180);

                $poster = SetMerchant::getLastOne(false);
                if ($poster && $poster['image']) {
                    $poster = $poster['image']['path'];
                    Qrcode::setPoster($name, $poster, $real, [95, 345]);
                }
            }

            $data = [
                'data' => $model,
                'qrcode' => $set->domain . $name,
                'qrcode_real' => $set->domain . $real,
                'debug_text' => $string,
            ];

            Cache::set($key, json_encode($data));

            return $this->successEncode($data);
        }

        return $this->fail();
    }

    /**
     * my (merchant) pay for list
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionPayFor()
    {
        $page = intval($this->post('page', $this->page));
        $pageSize = intval($this->post('pageSize', $this->pageSize));

        $query = MerchantOrder::find()
            ->where(['user_id' => $this->user->id])
            ->andWhere(['status' => 1]);
            // ->andWhere(['status' => 2]);

        $totalCount = $query->count();
        $totalPage = ceil($totalCount / $pageSize);

        $list = $query->orderBy(['id' => SORT_DESC])
            ->offset(($page - 1) * $pageSize)
            ->limit($pageSize)
            ->with(['payFor'])
            ->asArray()
            ->all();

        return $this->successEncode([
            $this->list => $list,
            $this->totalCount => (int)$totalCount,
            $this->totalPage => $totalPage,
            $this->currentPage => $page
        ]);
    }

    public function actionFetch()
    {
        $id = $this->post('id');

        $model = Model::find()
            ->where(['id' => $id])
            ->select(['id', 'nickname', 'name', 'mobile'])
            ->asArray()
            ->one();

        // need login
        $ticket = UserAccount::find()
            ->where(['user_id' => $this->user->id])
            ->select(['ticket'])
            ->scalar();

        if (!$model) {
            return $this->fail('商家错误');
        }

        $set = SetBasic::getLastOne();

        return $this->successEncode([
            'merchant' => $model,
            'mini' => $set->mini_merchant_pay,
            'ticket' => $ticket
        ]);
    }

    /**
     * create merchant pay order
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionSubmitPay()
    {
        $id = $this->post('id');
        $amount = floatval($this->post('amount'));

        $merchant = Model::findOne(['id' => $id]);
        if (!$merchant) {
            return $this->fail('商家错误');
        }

        $account = UserAccount::findOne(['user_id' => $this->user->id]);
        if (!$account) {
            return $this->fail('会员错误');
        }

        // ratio
        $ratio = (100 - $merchant->difference) / 100;

        if ($account->ticket >= $amount) {
            $ticket = $amount;
            $money = 0;
        } else {
            $ticket = floatval($account->ticket);
            $money = $amount - $ticket;
        }

        $platform = $amount * $ratio - $money;
        if ($platform < 0) {
            $platform = 0;
        }

        $model = new MerchantOrder();
        $model->sn = MerchantOrder::generateSn();
        $model->merchant_id = $merchant->id;
        $model->user_id = $account->user_id;
        $model->total = $amount;
        $model->money = $money;
        $model->ticket = $ticket;
        $model->platform = $platform;
        $model->status = 0;

        $model->save();

        if ($money == 0) {
            PaidFinish::merchant($model);
        }

        return $this->successEncode([
            'amount' => floatval($money),
            'merchant_order_id' => $model->id
        ]);
    }

    public function actionGetPayAmount()
    {
        $merchant_order_id = $this->post('merchant_order_id');

        $model = MerchantOrder::find()
            ->where(['id' => $merchant_order_id])
            ->andWhere(['user_id' => $this->user->id])
            ->one();

        if ($model) {
            return $this->successEncode([
                'amount' => $model->money,
                'sn' => $model->sn,
                'user_id' => $model->user_id
            ]);
        }

        return $this->fail();
    }
}